package com.vmove.childtrain.utils;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;

/**
 *@author gxd
 *@version 创建时间  2016-2-2  下午4:08:15
 *getBytes 得到byte[] 高位在前
 *getBytes1 得到byte[] 低位在前
 */
public class ByteUtil {

	public static byte[] getBytes(short data)  
    {  
        byte[] bytes = new byte[2];  
        bytes[1] = (byte) (data & 0xff);  
        bytes[0] = (byte) ((data & 0xff00) >> 8);  
        return bytes;  
    }

    /**
     * 低位在前
     * @param data
     * @return
     */
	public static byte[] getBytes1(short data)
	{  
		byte[] bytes = new byte[2];  
		bytes[0] = (byte) (data & 0xff);  
		bytes[1] = (byte) ((data & 0xff00) >> 8);  
		return bytes;  
	}

    /**
     * bytes[0] 高位
     * @param data
     * @return
     */
    public static byte[] getBytes(char data)  
    {  
        byte[] bytes = new byte[2];  
        bytes[1] = (byte) (data & 0xff);
        bytes[0] = (byte) (data >> 8);
        return bytes;  
    }  
    public static byte[] getBytes1(char data)
    {
        byte[] bytes = new byte[2];
        bytes[0] = (byte) (data);
        bytes[1] = (byte) (data >> 8);
        return bytes;
    }

    public static byte[] getBytes(int data)  
    {  
        byte[] bytes = new byte[4];  
        bytes[3] = (byte) (data & 0xff);  
        bytes[2] = (byte) ((data & 0xff00) >> 8);  
        bytes[1] = (byte) ((data & 0xff0000) >> 16);  
        bytes[0] = (byte) ((data & 0xff000000) >> 24);
        return bytes;  
    }

    /**
     * 低位在前
     * @param data
     * @return
     */
    public static byte[] getBytes1(int data)
    {  
    	byte[] bytes = new byte[4];  
    	bytes[0] = (byte) (data & 0xff);  
    	bytes[1] = (byte) ((data & 0xff00) >> 8);  
    	bytes[2] = (byte) ((data & 0xff0000) >> 16);  
    	bytes[3] = (byte) ((data & 0xff000000) >> 24);  
    	return bytes;  
    }  

    public static byte[] getBytes(long data)  
    {  
        byte[] bytes = new byte[8];  
        bytes[7] = (byte) (data & 0xff);
        bytes[6] = (byte) ((data >> 8) & 0xff);
        bytes[5] = (byte) ((data >> 16) & 0xff);
        bytes[4] = (byte) ((data >> 24) & 0xff);
        bytes[3] = (byte) ((data >> 32) & 0xff);
        bytes[2] = (byte) ((data >> 40) & 0xff);
        bytes[1] = (byte) ((data >> 48) & 0xff);
        bytes[0] = (byte) ((data >> 56) & 0xff);
        return bytes;  
    }

    /**
     * 低位在前
     * @param data
     * @return
     */
    public static byte[] getBytes1(long data)
    {
        byte[] bytes = new byte[8];
        bytes[0] = (byte) (data & 0xff);
        bytes[1] = (byte) ((data >> 8) & 0xff);
        bytes[2] = (byte) ((data >> 16) & 0xff);
        bytes[3] = (byte) ((data >> 24) & 0xff);
        bytes[4] = (byte) ((data >> 32) & 0xff);
        bytes[5] = (byte) ((data >> 40) & 0xff);
        bytes[6] = (byte) ((data >> 48) & 0xff);
        bytes[7] = (byte) ((data >> 56) & 0xff);
        return bytes;
    }

    public static byte[] getBytes(float data)  
    {  
        int intBits = Float.floatToIntBits(data);
        return getBytes(intBits);  
    }  
  
    public static byte[] getBytes(double data)  
    {  
        long intBits = Double.doubleToLongBits(data);
        return getBytes(intBits);  
    }  
  
    public static byte[] getBytes(String data, String charsetName)
    {  
        Charset charset = Charset.forName(charsetName);
        return data.getBytes(charset);  
    }  
  
    public static byte[] getBytes(String data)
    {  
        return getBytes(data, "GBK");  
    }  
  
      
    public static short getShort(byte[] bytes)  
    {  
        return (short) ((0xff & bytes[1]) | (0xff00 & (bytes[0] << 8)));  
    }  
  
    public static char getChar(byte[] bytes)  
    {  
        return (char) ((0xff & bytes[1]) | (0xff00 & (bytes[0] << 8)));
    }

    /**
     * 高位在前，低位在后
     * @param bytes
     * @return
     */
    public static int getInt(byte[] bytes)
    {  
        return (0xff & bytes[3]) | (0xff00 & (bytes[2] << 8)) | (0xff0000 & (bytes[1] << 16)) | (0xff000000 & (bytes[0] << 24));
    }  
     
    public static long getLong(byte[] bytes)  
    {  
        return(0xffL & (long)bytes[7]) | (0xff00L & ((long)bytes[6] << 8)) | (0xff0000L & ((long)bytes[5] << 16)) | (0xff000000L & ((long)bytes[4] << 24))
         | (0xff00000000L & ((long)bytes[3] << 32)) | (0xff0000000000L & ((long)bytes[2] << 40)) | (0xff000000000000L & ((long)bytes[1] << 48)) | (0xff00000000000000L & ((long)bytes[0] << 56));
    }  
  
    public static float getFloat(byte[] bytes)  
    {  
        return Float.intBitsToFloat(getInt(bytes));
    }  
  
    public static double getDouble(byte[] bytes)  
    {  
        long l = getLong(bytes);  
        System.out.println(l);
        return Double.longBitsToDouble(l);
    }  
  
    public static String getString(byte[] bytes, String charsetName)
    {  
        return new String(bytes, Charset.forName(charsetName));
    }

    /**
     * 0x80以下可以与 getByte(String s)还原
     * @param bytes
     * @return
     */
    public static String getString(byte[] bytes)
    {  
        return getString(bytes, "GBK");  
    }

    /**
     * 将byte数组转换为16进制格式的字符串
     * @param bytes byte数组
     * @param bSpace  是否在每两个数组中间添加空格
     * @return 返回16进制格式的字符串
     */
    public static String bytesToHexString(byte[] bytes, boolean bSpace)
    {
        if(bytes == null || bytes.length <= 0)
            return null;

        StringBuffer stringBuffer = new StringBuffer(bytes.length);
        String sTemp;

        for (int i = 0; i < bytes.length; i++)
        {
            sTemp = Integer.toHexString(0xFF & bytes[i]);
            sTemp = sTemp.toUpperCase();
            if (sTemp.length() < 2)
                stringBuffer.append(0);

            stringBuffer.append(sTemp);

            if(bSpace)
                stringBuffer.append(" ");
        }
        return stringBuffer.toString();
    }

    /**
     * 将字符串转换为byte数组
     * @param hexString 16进制格式的字符串（仅包含0-9，a-f,A-F,且长度为偶数)
     * @return 返回转换后的byte数组
     */
    public static byte[] hexStringToBytes(String hexString)
    {
        if(hexString == null)
            return null;

        hexString = hexString.replace(" ", "");
        hexString = hexString.toUpperCase();

        int len = (hexString.length() / 2);
        if(len <= 0)
            return null;

        byte[] result = new byte[len];
        char[] achar = hexString.toCharArray();
        for (int i = 0; i < len; i++)
        {
            int pos = i * 2;
            result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
        }

        return result;
    }

    /**
     * 将一个数组拷贝到另一个数组上
     *
     * @param dst 目标数组
     * @param dstOffset 目标数组偏移
     * @param src 源数组
     * @param srcOffset 源数组偏移
     * @param length 拷贝的长度
     *
     * @return 成功返回true，否则false
     */
    public static boolean cpyBytes(byte[] dst, int dstOffset, byte[] src, int srcOffset, int length)
    {
        if(dst == null || src == null ||
                dstOffset > dst.length || srcOffset > src.length ||
                length > (dst.length-dstOffset) || length > (src.length-srcOffset))
        {
            return false;
        }

        for (int i = 0; i < length; i++)
        {
            dst[i+dstOffset] = src[i+srcOffset];
        }

        return true;
    }

    /**
     * 连接两个byte[]
     * @param before
     * @param after
     * @return
     */
    public static byte[] connectBytes(byte[] before,byte[] after)
    {
        if(before == null || after == null)
        {
            return null;
        }

        byte[] des = new byte[before.length+after.length];

        for (int i = 0; i < des.length; i++)
        {
            if (i<before.length){
                des[i] =before[i];
            }
            else {
                des[i]=after[i-before.length];
            }
        }

        return des;
    }

    /**
     * 两个数组比较
     *
     * @param data1 数组1
     * @param data2 数组2
     *
     * @return 相等返回true，否则返回false
     */
    public static boolean cmpBytes(byte[] data1, byte[] data2)
    {
        if (data1 == null && data2 == null)
        {
            return true;
        }
        if (data1 == null || data2 == null)
        {
            return false;
        }
        if (data1 == data2)
        {
            return true;
        }
        if(data1.length != data2.length)
        {
            return false;
        }

        int len = data1.length;
        for (int i = 0; i < len; i++)
        {
            if(data1[i] != data2[i])
                return false;
        }

        return true;
    }

    private static int toByte(char c)
    {
        byte b = (byte) "0123456789ABCDEF".indexOf(c);
        return b;
    }

    /**
     * 获得指定文件的byte数组
     */
    public static byte[] getByteArrayFromFile(String filePath){
        byte[] buffer = null;
        try {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
            byte[] b = new byte[1000];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

    /**
     * 根据byte数组，生成文件
     */
    public static void getFileFromByteArray(byte[] bfile, String filePath, String fileName) {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            File dir = new File(filePath);
            if(!dir.exists()&&dir.isDirectory()){//判断文件目录是否存在
                dir.mkdirs();
            }
            file = new File(filePath+"\\"+fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bfile);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
}
